/**
 * 响应式布局管理器
 * 处理不同屏幕尺寸的适配和响应式设计
 */

/**
 * 断点配置接口
 * @typedef {Object} BreakpointConfig
 * @property {string} name
 * @property {number} minWidth
 * @property {number} maxWidth
 * @property {number} columns
 * @property {number} gutter
 * @property {number} margin
 */

/**
 * 响应式值接口
 * @template T
 * @typedef {Object} ResponsiveValue
 * @property {T} xs
 * @property {T} sm
 * @property {T} md
 * @property {T} lg
 * @property {T} xl
 * @property {T} default
 */

/**
 * 布局配置接口
 * @typedef {Object} LayoutConfig
 * @property {Object} container
 * @property {ResponsiveValue<number>} container.maxWidth
 * @property {ResponsiveValue<number>} container.padding
 * @property {Object} grid
 * @property {ResponsiveValue<number>} grid.columns
 * @property {ResponsiveValue<number>} grid.gutter
 * @property {Object} typography
 * @property {ResponsiveValue<number>} typography.fontSize
 * @property {ResponsiveValue<number>} typography.lineHeight
 * @property {Object} spacing
 * @property {ResponsiveValue<number>} spacing.xs
 * @property {ResponsiveValue<number>} spacing.sm
 * @property {ResponsiveValue<number>} spacing.md
 * @property {ResponsiveValue<number>} spacing.lg
 * @property {ResponsiveValue<number>} spacing.xl
 */

/**
 * 设备信息接口
 * @typedef {Object} DeviceInfo
 * @property {number} screenWidth
 * @property {number} screenHeight
 * @property {number} windowWidth
 * @property {number} windowHeight
 * @property {number} pixelRatio
 * @property {number} statusBarHeight
 * @property {Object} safeArea
 * @property {number} safeArea.top
 * @property {number} safeArea.bottom
 * @property {number} safeArea.left
 * @property {number} safeArea.right
 * @property {number} safeArea.width
 * @property {number} safeArea.height
 * @property {string} platform
 * @property {'portrait'|'landscape'} orientation
 */

class ResponsiveManager {
  constructor() {
    this.deviceInfo = null;
    this.currentBreakpoint = 'md';
    this.listeners = new Set();
    this.resizeTimer = null;
    this.isInitialized = false;

    // 断点配置
    this.breakpoints = {
    xs: {
      name: 'xs',
      minWidth: 0,
      maxWidth: 479,
      columns: 4,
      gutter: 8,
      margin: 16
    },
    sm: {
      name: 'sm',
      minWidth: 480,
      maxWidth: 767,
      columns: 8,
      gutter: 12,
      margin: 20
    },
    md: {
      name: 'md',
      minWidth: 768,
      maxWidth: 1023,
      columns: 12,
      gutter: 16,
      margin: 24
    },
    lg: {
      name: 'lg',
      minWidth: 1024,
      maxWidth: 1279,
      columns: 12,
      gutter: 20,
      margin: 32
    },
    xl: {
      name: 'xl',
      minWidth: 1280,
      columns: 12,
      gutter: 24,
      margin: 40
    }
    };

    // 布局配置
    this.layoutConfig = {
    container: {
      maxWidth: {
        xs: 320,
        sm: 480,
        md: 768,
        lg: 1024,
        xl: 1280
      },
      padding: {
        xs: 16,
        sm: 20,
        md: 24,
        lg: 32,
        xl: 40
      }
    },
    grid: {
      columns: {
        xs: 4,
        sm: 8,
        md: 12,
        lg: 12,
        xl: 12
      },
      gutter: {
        xs: 8,
        sm: 12,
        md: 16,
        lg: 20,
        xl: 24
      }
    },
    typography: {
      fontSize: {
        xs: 14,
        sm: 15,
        md: 16,
        lg: 17,
        xl: 18
      },
      lineHeight: {
        xs: 1.4,
        sm: 1.45,
        md: 1.5,
        lg: 1.55,
        xl: 1.6
      }
    },
    spacing: {
      xs: {
        xs: 4,
        sm: 6,
        md: 8,
        lg: 10,
        xl: 12
      },
      sm: {
        xs: 8,
        sm: 10,
        md: 12,
        lg: 14,
        xl: 16
      },
      md: {
        xs: 16,
        sm: 18,
        md: 20,
        lg: 22,
        xl: 24
      },
      lg: {
        xs: 24,
        sm: 26,
        md: 28,
        lg: 30,
        xl: 32
      },
      xl: {
        xs: 32,
        sm: 36,
        md: 40,
        lg: 44,
        xl: 48
      }
    }
    };

    this.init();
  }

  /**
   * 初始化响应式管理器
   */
  async init() {
    try {
      await this.updateDeviceInfo();
      this.updateBreakpoint();
      this.setupResizeListener();
      this.isInitialized = true;
      
      // 通知监听器
      this.notifyListeners();
    } catch (error) {
      console.error('响应式管理器初始化失败:', error);
    }
  }

  /**
   * 更新设备信息
   */
  updateDeviceInfo() {
    return new Promise((resolve) => {
      wx.getSystemInfo({
        success: (res) => {
          this.deviceInfo = {
            screenWidth: res.screenWidth,
            screenHeight: res.screenHeight,
            windowWidth: res.windowWidth,
            windowHeight: res.windowHeight,
            pixelRatio: res.pixelRatio,
            statusBarHeight: res.statusBarHeight,
            safeArea: res.safeArea || {
              top: res.statusBarHeight || 0,
              bottom: res.screenHeight,
              left: 0,
              right: res.screenWidth,
              width: res.screenWidth,
              height: res.screenHeight - (res.statusBarHeight || 0)
            },
            platform: res.platform,
            orientation: res.screenWidth > res.screenHeight ? 'landscape' : 'portrait'
          };
          resolve();
        },
        fail: () => {
          // 提供默认值
          this.deviceInfo = {
            screenWidth: 375,
            screenHeight: 667,
            windowWidth: 375,
            windowHeight: 667,
            pixelRatio: 2,
            statusBarHeight: 20,
            safeArea: {
              top: 20,
              bottom: 667,
              left: 0,
              right: 375,
              width: 375,
              height: 647
            },
            platform: 'unknown',
            orientation: 'portrait'
          };
          resolve();
        }
      });
    });
  }

  /**
   * 更新当前断点
   */
  updateBreakpoint() {
    if (!this.deviceInfo) return;
    
    const { windowWidth } = this.deviceInfo;
    let newBreakpoint = 'md';
    
    for (const [name, config] of Object.entries(this.breakpoints)) {
      if (windowWidth >= config.minWidth && 
          (!config.maxWidth || windowWidth <= config.maxWidth)) {
        newBreakpoint = name;
        break;
      }
    }
    
    if (newBreakpoint !== this.currentBreakpoint) {
      this.currentBreakpoint = newBreakpoint;
      this.notifyListeners();
    }
  }

  /**
   * 设置窗口大小变化监听
   */
  setupResizeListener() {
    // 小程序中监听窗口大小变化
    if (wx.onWindowResize) {
      wx.onWindowResize(() => {
        if (this.resizeTimer) {
          clearTimeout(this.resizeTimer);
        }
        
        this.resizeTimer = setTimeout(async () => {
          await this.updateDeviceInfo();
          this.updateBreakpoint();
        }, 100);
      });
    }
  }

  /**
   * 通知监听器
   */
  notifyListeners() {
    if (!this.deviceInfo) return;
    
    this.listeners.forEach(callback => {
      try {
        callback(this.currentBreakpoint, this.deviceInfo!);
      } catch (error) {
        console.error('响应式监听器执行失败:', error);
      }
    });
  }

  /**
   * 添加断点变化监听器
   */
  addBreakpointListener(callback) {
    this.listeners.add(callback);
    
    // 如果已初始化，立即调用一次
    if (this.isInitialized && this.deviceInfo) {
      callback(this.currentBreakpoint, this.deviceInfo);
    }
  }

  /**
   * 移除断点变化监听器
   */
  removeBreakpointListener(callback) {
    this.listeners.delete(callback);
  }

  /**
   * 获取当前断点
   */
  getCurrentBreakpoint() {
    return this.currentBreakpoint;
  }

  /**
   * 获取设备信息
   */
  getDeviceInfo() {
    return this.deviceInfo;
  }

  /**
   * 检查是否匹配断点
   */
  matchBreakpoint(breakpoint) {
    if (Array.isArray(breakpoint)) {
      return breakpoint.includes(this.currentBreakpoint);
    }
    return this.currentBreakpoint === breakpoint;
  }

  /**
   * 获取响应式值
   */
  getResponsiveValue(value) {
    // 按优先级获取值
    const breakpointOrder = ['xl', 'lg', 'md', 'sm', 'xs'];
    const currentIndex = breakpointOrder.indexOf(this.currentBreakpoint);
    
    // 从当前断点开始向下查找
    for (let i = currentIndex; i < breakpointOrder.length; i++) {
      const bp = breakpointOrder[i];
      if (value[bp] !== undefined) {
        return value[bp];
      }
    }
    
    // 如果没找到，返回默认值
    return value.default;
  }

  /**
   * 获取网格列数
   */
  getGridColumns() {
    return this.getResponsiveValue(this.layoutConfig.grid.columns) || 12;
  }

  /**
   * 获取网格间距
   */
  getGridGutter() {
    return this.getResponsiveValue(this.layoutConfig.grid.gutter) || 16;
  }

  /**
   * 获取容器最大宽度
   */
  getContainerMaxWidth() {
    return this.getResponsiveValue(this.layoutConfig.container.maxWidth) || 1200;
  }

  /**
   * 获取容器内边距
   */
  getContainerPadding() {
    return this.getResponsiveValue(this.layoutConfig.container.padding) || 24;
  }

  /**
   * 获取字体大小
   */
  getFontSize() {
    return this.getResponsiveValue(this.layoutConfig.typography.fontSize) || 16;
  }

  /**
   * 获取行高
   */
  getLineHeight() {
    return this.getResponsiveValue(this.layoutConfig.typography.lineHeight) || 1.5;
  }

  /**
   * 获取间距值
   */
  getSpacing(size) {
    return this.getResponsiveValue(this.layoutConfig.spacing[size]) || 16;
  }

  /**
   * 计算网格列宽
   */
  calculateColumnWidth(span, totalColumns) {
    const columns = totalColumns || this.getGridColumns();
    const gutter = this.getGridGutter();
    const containerWidth = this.deviceInfo?.windowWidth || 375;
    const padding = this.getContainerPadding();
    
    const availableWidth = containerWidth - (padding * 2);
    const totalGutters = (columns - 1) * gutter;
    const columnWidth = (availableWidth - totalGutters) / columns;
    
    return (columnWidth * span) + (gutter * (span - 1));
  }

  /**
   * 生成网格样式
   */
  generateGridStyles(span, offset = 0) {
    const columns = this.getGridColumns();
    const gutter = this.getGridGutter();
    
    const width = this.calculateColumnWidth(span);
    const marginLeft = offset > 0 ? this.calculateColumnWidth(offset) + gutter : 0;
    
    return {
      width: `${width}rpx`,
      marginLeft: `${marginLeft}rpx`,
      marginRight: `${gutter / 2}rpx`,
      marginBottom: `${gutter}rpx`
    };
  }

  /**
   * 生成响应式样式
   */
  generateResponsiveStyles(config) {
    const styles = {};
    
    Object.entries(config).forEach(([property, value]) => {
      if (value) {
        const responsiveValue = this.getResponsiveValue(value);
        if (responsiveValue !== undefined) {
          // 处理数值类型，自动添加rpx单位
          if (typeof responsiveValue === 'number' && 
              ['width', 'height', 'padding', 'margin', 'fontSize'].includes(property)) {
            styles[property] = `${responsiveValue}rpx`;
          } else {
            styles[property] = responsiveValue;
          }
        }
      }
    });
    
    return styles;
  }

  /**
   * 检查是否为移动设备
   */
  isMobile() {
    return this.matchBreakpoint(['xs', 'sm']);
  }

  /**
   * 检查是否为平板设备
   */
  isTablet() {
    return this.matchBreakpoint('md');
  }

  /**
   * 检查是否为桌面设备
   */
  isDesktop() {
    return this.matchBreakpoint(['lg', 'xl']);
  }

  /**
   * 检查是否为横屏
   */
  isLandscape() {
    return this.deviceInfo?.orientation === 'landscape';
  }

  /**
   * 检查是否为竖屏
   */
  isPortrait() {
    return this.deviceInfo?.orientation === 'portrait';
  }

  /**
   * 获取安全区域信息
   */
  getSafeArea() {
    return this.deviceInfo?.safeArea || null;
  }

  /**
   * 计算安全区域样式
   */
  getSafeAreaStyles() {
    const safeArea = this.getSafeArea();
    if (!safeArea) {
      return {
        paddingTop: '40rpx',
        paddingBottom: '40rpx'
      };
    }
    
    return {
      paddingTop: `${safeArea.top * 2}rpx`, // 转换为rpx
      paddingBottom: `${(this.deviceInfo!.screenHeight - safeArea.bottom) * 2}rpx`
    };
  }

  /**
   * 注册自定义断点
   */
  registerBreakpoint(name, config) {
    this.breakpoints[name] = config;
    this.updateBreakpoint();
  }

  /**
   * 更新布局配置
   */
  updateLayoutConfig(config) {
    this.layoutConfig = {
      ...this.layoutConfig,
      ...config
    };
  }

  /**
   * 获取断点配置
   */
  getBreakpointConfig(breakpoint) {
    const bp = breakpoint || this.currentBreakpoint;
    return this.breakpoints[bp] || null;
  }

  /**
   * 获取所有断点
   */
  getAllBreakpoints() {
    return { ...this.breakpoints };
  }

  /**
   * 转换像素到rpx
   */
  pxToRpx(px) {
    if (!this.deviceInfo) return px * 2;
    
    const { screenWidth, pixelRatio } = this.deviceInfo;
    return (px * 750) / screenWidth;
  }

  /**
   * 转换rpx到像素
   */
  rpxToPx(rpx) {
    if (!this.deviceInfo) return rpx / 2;
    
    const { screenWidth } = this.deviceInfo;
    return (rpx * screenWidth) / 750;
  }

  /**
   * 获取视口单位值
   */
  getViewportValue(value, unit) {
    if (!this.deviceInfo) return value;
    
    const { windowWidth, windowHeight } = this.deviceInfo;
    
    if (unit === 'vw') {
      return (value * windowWidth) / 100;
    } else {
      return (value * windowHeight) / 100;
    }
  }

  /**
   * 生成媒体查询样式
   */
  generateMediaQueryStyles(styles) {
    let css = '';
    
    Object.entries(styles).forEach(([breakpoint, rules]) => {
      const config = this.breakpoints[breakpoint];
      if (config) {
        const minWidth = config.minWidth;
        const maxWidth = config.maxWidth;
        
        let mediaQuery = '';
        if (maxWidth) {
          mediaQuery = `@media (min-width: ${minWidth}px) and (max-width: ${maxWidth}px)`;
        } else {
          mediaQuery = `@media (min-width: ${minWidth}px)`;
        }
        
        css += `${mediaQuery} {\n`;
        Object.entries(rules).forEach(([selector, properties]) => {
          css += `  ${selector} {\n`;
          Object.entries(properties).forEach(([prop, value]) => {
            css += `    ${prop}: ${value};\n`;
          });
          css += `  }\n`;
        });
        css += `}\n`;
      }
    });
    
    return css;
  }

  /**
   * 清理资源
   */
  cleanup() {
    if (this.resizeTimer) {
      clearTimeout(this.resizeTimer);
      this.resizeTimer = null;
    }
    
    this.listeners.clear();
    
    // 移除窗口大小变化监听
    if (wx.offWindowResize) {
      wx.offWindowResize();
    }
  }
}

// 创建全局实例
const responsiveManager = new ResponsiveManager();

module.exports = responsiveManager;
module.exports.ResponsiveManager = ResponsiveManager;